/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package model;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import util.Utilities;
/**
 *
 * @author Asus
 */
public class FileInfo {
    private String filePath;
    private String fileCheckSum;
    private int version;
    private int fileType;
    
    public FileInfo(){
        fileCheckSum = "";
    }
    
    public FileInfo(FileInfo mFileInfo){
        this.fileCheckSum = "" + mFileInfo.fileCheckSum;
        this.filePath = "" + mFileInfo.filePath;
        this.version = mFileInfo.version;
        this.fileType = mFileInfo.fileType;
        
    }

    public String getFileCheckSum() {
        return fileCheckSum;
    }

    public void setFileCheckSum(String fileCheckSum) {
        this.fileCheckSum = fileCheckSum;
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public int getFileType() {
        return fileType;
    }

    public void setFileType(int fileType) {
        this.fileType = fileType;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }
    
    public static FileInfo createFileInfo(String filepath){
        FileInfo info = new FileInfo();
        
        info.filePath = filepath;
        info.version = 1;
        
        try{
            if(new File(filepath).isDirectory()){
                info.fileCheckSum = Utilities.convertToSHA1(filepath); //konvert filepath pake SHA1
                info.fileType = Utilities.TYPE_FOLDER; //tipe folder
            } else {
               info.fileCheckSum = Utilities.convertToSHA1(Utilities.getFileByte(filepath));
               info.fileType = Utilities.TYPE_FILE;
            }
        } catch (Exception ex) {
            System.out.println("Failed in making file infos. Reason = " + ex);
        }
        
        return info;
    }
    
    public static ArrayList<FileInfo> readFileInfos (String filePath) throws FileNotFoundException{
        return readFileInfos(Utilities.getFileByte(filePath));
    }
    
    public static ArrayList<FileInfo> readFileInfos (byte[] data){
        int fileCount = data[0];
        fileCount = (data[0] + 256) % 256;
        fileCount = (fileCount << 8) + (data[1] + 256) % 256;
        fileCount = (fileCount << 8) + (data[2] + 256) % 256;
        fileCount = (fileCount << 8) + (data[3] + 256) % 256;

        ArrayList<FileInfo> result = new ArrayList<FileInfo>();

        int last = 4;

        for (int i = 0; i < fileCount; ++i) {
            FileInfo fileInfo = new FileInfo();

            int fileLength = data[last];
            ++last;

            StringBuilder sb = new StringBuilder();

            for (int j = 0; j < fileLength; ++j) {
                sb.append((char)data[last]);
                ++last;
            }
            fileInfo.filePath = sb.toString();

            fileInfo.fileType = data[last];
            ++last;

            fileInfo.version = (data[last] + 256) % 256; ++last;
            fileInfo.version = ((fileInfo.version << 8) + data[last] + 256) % 256; ++last;
            fileInfo.version = ((fileInfo.version << 8) + data[last] + 256) % 256; ++last;
            fileInfo.version = ((fileInfo.version << 8) + data[last] + 256) % 256; ++last;

            for (int j = 0; j < 40; ++j) {
                fileInfo.fileCheckSum += (char)data[last];
                ++last;
            }

            result.add(fileInfo);
        }

        return result;
    }
    
    public void writeFileInfo(BufferedOutputStream fileInfoStream){
        int length = filePath.length();
        try {
            //menuliskan panjang file
            fileInfoStream.write((byte)length);
            
            //menuliskan nama file
            for(int i=0;i<length;i++){
                fileInfoStream.write(filePath.charAt(i));
            }
            
            //menuliskan tipe file
            fileInfoStream.write((byte)fileType);
            
            //menuliskan revisi ke-x file
            fileInfoStream.write((byte)((version >> 24) % 256));
            fileInfoStream.write((byte)((version >> 16) % 256));
            fileInfoStream.write((byte)((version >> 8) % 256));
            fileInfoStream.write((byte)(version % 256));
            
            //menuliskan checksum file
            for(int i=0;i<40;i++){
                fileInfoStream.write(fileCheckSum.charAt(i));
            }
        } catch (IOException ex) {
            Logger.getLogger(FileInfo.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public byte[] wrapPackage(){
        byte[] result = null;
        StringBuilder sb = new StringBuilder();
        int length = filePath.length();
        
        sb.append((char)length);
        
        //menuliskan nama file
        for(int i=0; i<length;i++){
            sb.append(filePath.charAt(i));
        }
        
        //menuliskan tipe file
        sb.append((char)fileType);
        
        //menuliskan revisi ke-x
        sb.append((char)((version >> 24) % 256));
        sb.append((char)((version >> 16) % 256));
        sb.append((char)((version >> 8) % 256));
        sb.append((char)(version % 256));
        
        //menuliskan checksum
        // tulis checksum
        for (int i = 0; i < 40; ++i)
            sb.append((char)fileCheckSum.charAt(i));


        String str = sb.toString();
        result = new byte[str.length()];

        for (int i = 0; i < result.length; ++i)
            result[i] = (byte)str.charAt(i);

        return result;
    }
    
    public byte[] toSend() {
        StringBuilder sb = new StringBuilder();
        int length = filePath.length();

        sb.append((char)length);

        // tulis file name
        for (int i = 0; i < length; ++i)
            sb.append(filePath.charAt(i));

        // tulis tipe file
        sb.append((char)fileType);

        // tulis nomer revisi
        sb.append((char)((version >> 24) % 256));
        sb.append((char)((version >> 16) % 256));
        sb.append((char)((version >> 8) % 256));
        sb.append((char)(version % 256));

        // tulis checksum
        for (int i = 0; i < 40; ++i)
            sb.append((char)fileCheckSum.charAt(i));


        String str = sb.toString();
        byte[] result = new byte[str.length()];

        for (int i = 0; i < result.length; ++i)
            result[i] = (byte)str.charAt(i);

        return result;
    }
    
}
